/*******************************************************************************
 * Copyright (C), 2014, BeeIoT Tech. Co., Ltd. 
 * FileName:      object.c
 * Author:        lvxin 
 * Version :      1.0
 * Date:          2014-09-04 15:52:52
 * Description:   用于分割字符串，并按需获得相应字段
 * Function List: 
 *                 object_string_split            
 *                 object_string_get_field_string 
 *                 object_string_get_field_total  
 *                 object_free                    
 * History:
 * <author>   <time>                <version >  <desc> 
 * lvxin      2014-09-04 15:52:52   1.0.0         build this moudle 
 ******************************************************************************/

/*******************************************************************************
 *  *INCLUDES
 *  */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "object.h"

/*******************************************************************************
 *  *PUBLIC FUNCTIONS
 *  */

/*******************************************************************************
 * Function:      object_string_split()
 * Description:   以FS为分隔符分割字符串
 * Calls:         malloc、realloc
 * Called By:      
 * Input:         string --原始字符串
 *                  FS   --分隔符
 *                  type --字符串是否带双引号 NOQUOTES --不带 
 *                                            QUOTES   --带
 * Return:        object_t * --返回malloc的结构体指针
 * Others:        使用后需要用object_free释放掉
 ******************************************************************************/
object_t *object_string_split (const char *string, char FS, char type)
{
    object_t *tmp;
    const char *start = string; //记录字符串起始位置
    const char *end = string; //记录字符串终止位置
    uint32_t count = 0;  //记录字符的个数
    char double_quotes = 0; //1-进入字段的双引号内, 0-不在字段的双引号内
    int i = 0;
    int p = 0; //不带双引号时指示当前字符位置

    if (string == NULL)
    {
        return NULL;
    }
    tmp = (object_t *) calloc (1, sizeof (object_t));
    tmp->FS = FS; //分隔符
    tmp->src = string;

    /*开始查找*/
    while (*string != '\0' && *string != '\r' && *string != '\n')
    {
        while ( *string != FS && 
                *string !='\0'
                )
        {
            if (*(string) == ' ') //空格时跳过处理
            {
                string ++;
                continue;
            }

            if(*string == '\r' || *string == '\n') //表示行结束
            {
                break;
            }

            do
            {
                if (*string == '\"')
                {
                    if (*(string - 1) != '\\')
                    double_quotes = (double_quotes==0)?1:0;
                }
                string ++;
            }
            while(double_quotes == 1);
        }
        end = string;
        tmp->field_list = (char **) realloc (tmp->field_list, 
                sizeof(char *)*(tmp->NF+1));
        count = (end - start)<0?0-(end - start):(end - start);
        /*printf ("[sizeof(char *)] %d\t[count]%d\n",sizeof(char *)*tmp->NF ,count);*/
        tmp->field_list[tmp->NF] = (char *) calloc (1, count + 1); //给字段分配空间

        if (count != 0)
        {
            p = 0;
            switch (type)
            {
                case QUOTES :
                    {
                        strncpy (tmp->field_list[tmp->NF], start, count);
                    }
                    break;
                case NOQUOTES : //没有双引号的
                    {
                       for (i = 0; i < count; i ++)
                       {
                           if (start[i] == '"' &&
                                start[i<1?0:i-1] !='\\'   
                                   )
                           {
                               continue;
                           }
                           tmp->field_list[tmp->NF][p] = start[i];
                           p ++;
                       }
                    }
                    break;
                default :
                    break;
            }
        }
        tmp->NF ++;
        if (*string == '\0')
        {
            break;
        }
        string ++;
        start = string;
    }
    /*查找完毕*/
    return tmp;
}


/*******************************************************************************
 * Function:      object_string_get_field_string()
 * Description:   获得第N个匹配的字段
 * Calls:         None
 * Called By:     
 * Input:         object --对象
 * Return:        字符串地址
 * Others:        None
 ******************************************************************************/
char * object_string_get_field_string(object_t *object, int index)
{
    if (index > object->NF || object == NULL)
    {
        return NULL;
    }
    if (index == 0)
    {
        return (char *)object->src;
    }
    return object->field_list[index-1];
}

/*******************************************************************************
 * Function:      object_string_get_field_total()
 * Description:   获得分割字段的总数
 * Calls:         None
 * Called By:     
 * Input:         object --对象
 * Return:        字符串地址
 * Others:        None
 ******************************************************************************/
int object_string_get_field_total (object_t *object)
{
    if (object == NULL) return -1;
    return object->NF;
}

/*******************************************************************************
 * Function:      object_free()
 * Description:   释放使用过的object_t对象的内存空间
 * Calls:         free
 * Called By:      
 * Input:         object --创建过的对象
 * Return:        None
 * Others:        None
 ******************************************************************************/
void object_free(object_t *object)
{
    int i;
    if (object == NULL) return;

    for (i = 0; i < object->NF; i ++)
    {
        free (object->field_list[i]);
    }
    free (object->field_list);
    free (object);
}

